package com.gscitysfy.cus.drain.modules.inspection.service.impl;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gscitysfy.cloudfrmwk.security.utils.SecurityUtils;
import com.gscitysfy.cus.drain.constants.DicConstant;
import com.gscitysfy.cus.drain.constants.RedisKeyConstant;
import com.gscitysfy.cus.drain.modules.common.entity.DrainInspectionMnFile;
import com.gscitysfy.cus.drain.modules.common.service.IFileService;
import com.gscitysfy.cus.drain.modules.inspection.entity.DrainInspectionMnOrder;
import com.gscitysfy.cus.drain.modules.inspection.entity.DrainInspectionMnProblem;
import com.gscitysfy.cus.drain.modules.inspection.mapper.DrainInspectionMnOrderMapper;
import com.gscitysfy.cus.drain.modules.inspection.mapper.DrainInspectionMnProblemMapper;
import com.gscitysfy.cus.drain.modules.inspection.service.IDrainInspectionMnProblemService;
import com.gscitysfy.cus.drain.modules.inspection.vo.DrainInspectionMnProblemVo;
import com.gscitysfy.cus.drain.modules.inspection.vo.NumVo;
import com.gscitysfy.cus.drain.utils.DateUtil;
import com.gscitysfy.cus.drain.utils.HttpResponseUtil;
import com.gscitysfy.cus.drain.utils.RedisUtil;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;


/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Administrator
 * @since 2022-10-14 15:00:46
 */
@Service
public class DrainInspectionMnProblemServiceImpl extends ServiceImpl<DrainInspectionMnProblemMapper, DrainInspectionMnProblem> implements IDrainInspectionMnProblemService {

    @Resource
    private DrainInspectionMnProblemMapper drainInspectionMnProblemMapper;

    @Resource
    private IFileService iFileService;

    @Resource
    private DrainInspectionMnOrderMapper orderMapper;

    @Resource
    private RedisUtil redisUtil;


    /**
     * APP新增维养问题
     *
     * @param drainInspectionMnProblem
     * @return
     */
    @Override
    public boolean saveProblem(DrainInspectionMnProblem drainInspectionMnProblem) {
        drainInspectionMnProblem.setCmKid(null);
        drainInspectionMnProblem.setCmProblemNo(this.createPlanNo(drainInspectionMnProblem.getCmProblemNo()));
        String userId = SecurityUtils.getPrincipal().getUserId();
        String username = SecurityUtils.getPrincipal().getName();
        String phoneNumber = SecurityUtils.getPrincipal().getPhoneNumber();

        drainInspectionMnProblem.setCmProblemReportUserId(Long.parseLong(userId));
        drainInspectionMnProblem.setCmProblemReportUserName(username);
        drainInspectionMnProblem.setCmProblemReportUserPhone(phoneNumber);
        drainInspectionMnProblem.setCmProblemIsCreateOrder(0);

        Date date = new Date();
        drainInspectionMnProblem.setCmProblemReportTime(date);
        drainInspectionMnProblem.setCmProblemStatus("wtzt2");
        drainInspectionMnProblem.setCmProblemApprovalStatus(0);
        return this.save(drainInspectionMnProblem);
    }


    /**
     * 删除维养问题
     *
     * @param ids
     * @return
     */
    @Override
    public int deleteProblemByIds(String ids) {
        String[] arry = ids.split(",");
        drainInspectionMnProblemMapper.deleteId(Arrays.asList(arry));
        return 1;
    }


    /**
     * 查询问题详情
     *
     * @param id
     * @return
     */
    @Override
    public DrainInspectionMnProblem viewById(String id) {
        DrainInspectionMnProblem drainInspectionMnProblem = drainInspectionMnProblemMapper.selectById(id);
        List<DrainInspectionMnFile> fileListByIds = iFileService.getFileListByIds(drainInspectionMnProblem.getCmProblemAttachment());
        drainInspectionMnProblem.setFileList(fileListByIds);
        return drainInspectionMnProblem;
    }


    /**
     * 分页获取维养问题单列表
     * @param drainInspectionMnProblemVo
     * @return
     */
    @Override
    public IPage<DrainInspectionMnProblem> getProblemListByCondition(DrainInspectionMnProblemVo drainInspectionMnProblemVo) {
        LambdaQueryWrapper<DrainInspectionMnProblem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DrainInspectionMnProblem::getCmUsable, false);
        // 查询条件判断
        if (StringUtils.isNotEmpty(drainInspectionMnProblemVo.getCmProblemNo())) {
            queryWrapper.like(DrainInspectionMnProblem::getCmProblemNo, drainInspectionMnProblemVo.getCmProblemNo());
        }
        if (StringUtils.isNotEmpty(drainInspectionMnProblemVo.getCmProblemBasis())) {
            queryWrapper.eq(DrainInspectionMnProblem::getCmProblemBasis, drainInspectionMnProblemVo.getCmProblemBasis());
        }
        if (StringUtils.isNotEmpty(drainInspectionMnProblemVo.getCmProblemType())) {
            queryWrapper.eq(DrainInspectionMnProblem::getCmProblemType, drainInspectionMnProblemVo.getCmProblemType());
        }
        //问题审核状态
        if (Objects.nonNull(drainInspectionMnProblemVo.getCmProblemApprovalStatus())) {
            queryWrapper.eq(DrainInspectionMnProblem::getCmProblemApprovalStatus, drainInspectionMnProblemVo.getCmProblemApprovalStatus());
        }
        //问题状态
        if (StringUtils.isNotEmpty(drainInspectionMnProblemVo.getCmProblemStatus())) {
            queryWrapper.eq(DrainInspectionMnProblem::getCmProblemStatus, drainInspectionMnProblemVo.getCmProblemStatus());
        }
        //是否创建维修单
        if (Objects.nonNull(drainInspectionMnProblemVo.getCmProblemIsCreateOrder())) {
            queryWrapper.eq(DrainInspectionMnProblem::getCmProblemIsCreateOrder, drainInspectionMnProblemVo.getCmProblemIsCreateOrder());
        }
        // 判断时间
        if (Objects.nonNull(drainInspectionMnProblemVo.getCmStartProblemReportTime())) {
            queryWrapper.ge(DrainInspectionMnProblem::getCmProblemReportTime, drainInspectionMnProblemVo.getCmStartProblemReportTime());
        }
        if (Objects.nonNull(drainInspectionMnProblemVo.getCmEndProblemReportTime())) {
            queryWrapper.le(DrainInspectionMnProblem::getCmProblemReportTime, drainInspectionMnProblemVo.getCmEndProblemReportTime());
        }
        return this.page(new Page<>(drainInspectionMnProblemVo.getCurrent(), drainInspectionMnProblemVo.getSize()), queryWrapper);
    }

    /**
     * 导出维养问题
     *
     * @param response
     * @param drainInspectionMnProblemVo
     */
    @Override
    public void exportPatrolFile(HttpServletResponse response, DrainInspectionMnProblemVo drainInspectionMnProblemVo) {
        try (ExcelWriter writer = ExcelUtil.getWriter(true); OutputStream out = response.getOutputStream()) {

            String filename = "维养问题信息表.xlsx";
            HttpResponseUtil.setResponseHeaders(response, filename);
            writer.setOnlyAlias(true);
            //设置表头
            writer.addHeaderAlias("cmProblemNo", "问题编号");
            writer.addHeaderAlias("cmProblemReportTime", "问题上报时间");
            writer.addHeaderAlias("cmProblemBasis", "问题依据");
            writer.addHeaderAlias("cmProblemType", "问题类别");
            writer.addHeaderAlias("cmProblemDetail", "问题详情");
            writer.addHeaderAlias("cmProblemLocationDetail", "位置描述");
            writer.addHeaderAlias("cmProblemReportUserName", "上报人姓名");
            writer.addHeaderAlias("cmProblemReportUserPhone", "上报人电话");
            writer.addHeaderAlias("cmProblemIsCreateOrderDesc", "是否创建维修单");
            writer.addHeaderAlias("cmProblemStatus", "问题状态");
            writer.addHeaderAlias("cmProblemApprovalStatusDesc", "问题审核状态");

            List<DrainInspectionMnProblem> problemFileListByCondition = this.getProblemFileListByCondition(drainInspectionMnProblemVo);

            //判空，单独写入头数据
            if (problemFileListByCondition.isEmpty()) {
                writer.writeHeadRow(new ArrayList<String>() {{
                    add("问题编号");
                    add("问题上报时间");
                    add("问题依据");
                    add("问题类别");
                    add("问题详情");
                    add("位置描述");
                    add("上报人姓名");
                    add("上报人电话");
                    add("是否创建维修单");
                    add("问题状态");
                    add("问题审核状态（万元）");
                }});
            } else {

                Map<Object, Object> problemBasis = redisUtil.hmget(RedisKeyConstant.DATA_DICT_KEY + DicConstant.PROBLEM_BASIS);
                Map<Object, Object> problemType = redisUtil.hmget(RedisKeyConstant.DATA_DICT_KEY + DicConstant.PLAN_OBJECT_TYPE);
                Map<Object, Object> problemStatus = redisUtil.hmget(RedisKeyConstant.DATA_DICT_KEY + DicConstant.JOB_STATUS);

                problemFileListByCondition.forEach(item -> {
                    item.setCmProblemBasis(problemBasis.get(item.getCmProblemBasis()).toString());
                    item.setCmProblemType(problemType.get(item.getCmProblemType()).toString());
                    item.setCmProblemStatus(problemStatus.get(item.getCmProblemStatus()).toString());
                    item.setCmProblemIsCreateOrderDesc(item.getCmProblemIsCreateOrderDesc());
                });
                writer.write(problemFileListByCondition, true);
                writer.flush(out);
            }

        } catch (IOException e) {
            log.error("export Problem list error!");
        }
    }


    /**
     * 复核
     * @param cmKid
     * @param cmProblemApprovalStatus
     * @param cmProblemApprovalComments
     * @return
     */
    @Override
    public Object updateProblemById(Long cmKid, Integer cmProblemApprovalStatus, String cmProblemApprovalComments) {
        DrainInspectionMnProblem byId = getById(cmKid);
        byId.setCmProblemApprovalStatus(cmProblemApprovalStatus);
        byId.setCmProblemApprovalComments(cmProblemApprovalComments);
        return this.saveOrUpdate(byId);
    }


    /**
     * 生成问题编号
     * @param type
     * @return
     */
    private String createPlanNo(String type){
        String nextNo = "WYWT" + DateUtil.formatDate(new Date(), DateUtil.yyyy_MM_dd_HH_mm);

        LambdaQueryWrapper<DrainInspectionMnProblem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.likeRight(DrainInspectionMnProblem::getCmProblemNo, nextNo).orderByDesc(DrainInspectionMnProblem::getCmAddtime).last("limit 1");
        DrainInspectionMnProblem plan = this.getOne(queryWrapper);
        if (!Objects.isNull(plan)){
            String preNo = plan.getCmProblemNo();
            String time = preNo.substring(preNo.length() - 3);
            String num = preNo.substring(0, preNo.length() - 3);
            DecimalFormat format = new DecimalFormat("000");
            nextNo = time + format.format(Integer.parseInt(num) + 1);
        }else{
            nextNo = nextNo + "001";
        }
        return nextNo;
    }


    /**
     * APP新增问题接口
     * @param drainInspectionMnProblem
     * @return
     */
    @Override
    public Long appSaveProblem(DrainInspectionMnProblem drainInspectionMnProblem) {
        drainInspectionMnProblem.setCmKid(null);
        drainInspectionMnProblem.setCmProblemNo(this.createPlanNo(drainInspectionMnProblem.getCmProblemNo()));
        String userId = SecurityUtils.getPrincipal().getUserId();
        String username = SecurityUtils.getPrincipal().getName();
        String phoneNumber = SecurityUtils.getPrincipal().getPhoneNumber();

        drainInspectionMnProblem.setCmProblemReportUserId(Long.parseLong(userId));
        drainInspectionMnProblem.setCmProblemReportUserName(username);
        drainInspectionMnProblem.setCmProblemReportUserPhone(phoneNumber);
        drainInspectionMnProblem.setCmProblemIsCreateOrder(0);

        Date date = new Date();
        drainInspectionMnProblem.setCmProblemReportTime(date);
        drainInspectionMnProblem.setCmProblemStatus("wtzt2");
        drainInspectionMnProblem.setCmProblemBasis("wtyj1");
        drainInspectionMnProblem.setCmProblemApprovalStatus(0);
        //小程序端问题直接上报标识
        drainInspectionMnProblem.setProblemType(0);

        this.save(drainInspectionMnProblem);
        return drainInspectionMnProblem.getCmKid();
    }


    /**
     * APP新增问题是否处置完毕
     * @param drainInspectionMnProblem
     * @return
     */
    @Override
    public boolean appUpdateProblem(DrainInspectionMnProblem drainInspectionMnProblem) {
        return this.updateById(drainInspectionMnProblem);
    }


    /**
     * 上报问题数量
     * @param type
     * @return
     */
    @Override
    public NumVo appCountProblem(String type) {
        String userId = SecurityUtils.getPrincipal().getUserId();

        NumVo num = new NumVo();
        String date = null;
        if(DateUtil.DAY.equals(type)){
            date = DateUtil.formatDate(new Date(),"yyyy-MM-dd" ) + "%";
            num.setInspectionDistance(12.4);
        }
        if(DateUtil.MONTH.equals(type)){
            date = DateUtil.formatDate(new Date(),"yyyy-MM" ) + "%";
            num.setInspectionDistance(139.3);
        }

        //问题上报数
        LambdaQueryWrapper<DrainInspectionMnProblem> queryWrapper =  new LambdaQueryWrapper<>();
        queryWrapper.eq(DrainInspectionMnProblem::getCmProblemReportUserId, Long.parseLong(userId))
                .apply(StringUtils.isNotEmpty(date), "CAST(cm_addtime as VARCHAR) like {0}", date);

        num.setReportProblemNum(this.count(queryWrapper));

        //问题解决数
        LambdaQueryWrapper<DrainInspectionMnOrder> orderQuery =  new LambdaQueryWrapper<>();
        orderQuery.eq(DrainInspectionMnOrder::getCmOrderReportUserId, Long.parseLong(userId))
                .apply(StringUtils.isNotEmpty(date), "CAST(cm_addtime as VARCHAR) like {0}", date);
        num.setSolveProblemNum(orderMapper.selectCount(orderQuery));
        return num;
    }


    /**
     * 导出问题列表
     * @param drainInspectionMnProblemVo
     * @return
     */
    public List<DrainInspectionMnProblem> getProblemFileListByCondition(DrainInspectionMnProblemVo drainInspectionMnProblemVo) {
        LambdaQueryWrapper<DrainInspectionMnProblem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DrainInspectionMnProblem::getCmUsable, false);
        // 查询条件判断
        if (StringUtils.isNotEmpty(drainInspectionMnProblemVo.getCmProblemNo())) {
            queryWrapper.like(DrainInspectionMnProblem::getCmProblemNo, drainInspectionMnProblemVo.getCmProblemNo());
        }
        if (StringUtils.isNotEmpty(drainInspectionMnProblemVo.getCmProblemBasis())) {
            queryWrapper.eq(DrainInspectionMnProblem::getCmProblemBasis, drainInspectionMnProblemVo.getCmProblemBasis());
        }
        if (StringUtils.isNotEmpty(drainInspectionMnProblemVo.getCmProblemType())) {
            queryWrapper.eq(DrainInspectionMnProblem::getCmProblemType, drainInspectionMnProblemVo.getCmProblemType());
        }
        if (StringUtils.isNotEmpty(drainInspectionMnProblemVo.getCmProblemApprovalComments())) {
            queryWrapper.eq(DrainInspectionMnProblem::getCmProblemApprovalComments, drainInspectionMnProblemVo.getCmProblemApprovalComments());
        }
        if (StringUtils.isNotEmpty(drainInspectionMnProblemVo.getCmProblemStatus())) {
            queryWrapper.eq(DrainInspectionMnProblem::getCmProblemStatus, drainInspectionMnProblemVo.getCmProblemStatus());
        }
        if (Objects.nonNull(drainInspectionMnProblemVo.getCmProblemIsCreateOrder())) {
            queryWrapper.eq(DrainInspectionMnProblem::getCmProblemIsCreateOrder, drainInspectionMnProblemVo.getCmProblemIsCreateOrder());
        }
        // 判断时间
        if (Objects.nonNull(drainInspectionMnProblemVo.getCmStartProblemReportTime())) {
            queryWrapper.ge(DrainInspectionMnProblem::getCmProblemReportTime, drainInspectionMnProblemVo.getCmStartProblemReportTime());
        }
        if (Objects.nonNull(drainInspectionMnProblemVo.getCmEndProblemReportTime())) {
            queryWrapper.le(DrainInspectionMnProblem::getCmProblemReportTime, drainInspectionMnProblemVo.getCmEndProblemReportTime());
        }
        if(StringUtils.isNotEmpty(drainInspectionMnProblemVo.getIds())){
            queryWrapper.clear();
            queryWrapper.in(DrainInspectionMnProblem::getCmKid, Arrays.stream(drainInspectionMnProblemVo.getIds().split(StrUtil.COMMA)).map(Long::parseLong).collect(Collectors.toList()));
        }
        return this.list(queryWrapper);
    }
}